/**
 * ImportStepThree
 */
layui.define(['jquery', 'yunj', "ImportStep", "table", "element"], function (exports) {

    let win = window;
    let doc = document;
    let $ = layui.jquery;
    let ImportStep = layui.ImportStep;
    let table = layui.table;
    let element = layui.element;

    class ImportStepThree extends ImportStep {

        constructor(importObj) {
            super(importObj, "three", "第三步：导入数据");
            this.importItems = [];                      // 上传数据
            this.importItemIdx = 0;                     // 上传数据索引
            this.rawTable = false;                     // 来源表格对象
            this.sheetItems = {};                       // 上传数据，有sheet则为{sheet=>[item1,..],...}，反之为[item1,..]
            this.dataTotalCount = 0;                    // 上传数据总量
            this.dataErrorCount = 0;                    // 上传数据错误量
            this.dataSuccessCount = 0;                  // 上传数据成功量
            this.dataFailCount = 0;                     // 上传数据失败量
            this.sheetTableBoxEl = null;                // 上传数据工作表表格父级元素
            this.dataTotalCountEl = null;               // 上传数据总量元素
            this.dataErrorCountEl = null;               // 上传错误数据量元素
            this.dataSuccessCountEl = null;             // 上传成功数据量元素
            this.dataFailCountEl = null;                // 上传失败数据量元素
            this.btnImportHandleEl = null;              // 确认上传处理按钮元素

            // 上传处理按钮状态枚举
            this.BtnImportHandleStatusEnum = {
                IMPORT: {code: "import", tips: "立即导入", canClick: true},
                IMPORTING: {code: "importing", tips: "正在导入", canClick: false},
                COMPLETED: {code: "completed", tips: "完成", canClick: true},
                NO_DATA: {code: "no_data", tips: "暂无数据可导入", canClick: false},
            };
        }

        async render(refresh = false) {
            let that = this;
            if (!refresh) return;
            that._setContentBoxHtml();
            that._setUploadData();
            that._renderSheetTable();
        }

        // 获取上传数据总量
        _getDataTotalCount() {
            return this.dataTotalCount;
        }

        // 设置上传数据总量
        _setDataTotalCount(count) {
            this.dataTotalCount = count;
            this.dataTotalCountEl.html(count);
        }

        // 获取上传数据错误量
        _getDataErrorCount() {
            return this.dataErrorCount;
        }

        // 设置上传数据错误量
        _setDataErrorCount(count) {
            this.dataErrorCount = count;
            this.dataErrorCountEl.html(count);
        }

        // 获取上传数据成功量
        _getDataSuccessCount() {
            return this.dataSuccessCount;
        }

        // 设置上传数据成功量
        _setDataSuccessCount(count) {
            this.dataSuccessCount = count;
            this.dataSuccessCountEl.html(count);
        }

        // 获取上传数据失败量
        _getDataFailCount() {
            return this.dataFailCount;
        }

        // 设置上传数据失败量
        _setDataFailCount(count) {
            this.dataFailCount = count;
            this.dataFailCountEl.html(count);
        }

        // 设置内容区域html
        _setContentBoxHtml() {
            let that = this;
            if (that.contentBoxEl.html().length <= 0) {
                that.contentBoxEl.html(`<div class="yunj-import-step-content-row import-progress-box">
                                            <div class="import-progress layui-progress layui-progress-big" lay-filter="import_progress" lay-showPercent="true">
                                                <div class="layui-progress-bar layui-bg-red" lay-percent="0%"></div>
                                            </div>
                                        </div>
                                        <div class="yunj-import-step-content-row import-action">
                                            <div class="desc">
                                                <div class="item total">合计：<span class="count">${that._getDataTotalCount()}</span></div>
                                                <div class="item error">错误：<span class="count">${that._getDataErrorCount()}</span></div>
                                                <div class="item success">成功：<span class="count">${that._getDataSuccessCount()}</span></div>
                                                <div class="item fail">失败：<span class="count">${that._getDataFailCount()}</span></div>
                                            </div>
                                            <div class="action">
                                                <button type="button" class="layui-btn layui-btn-sm layui-btn-primary btn-import-handle"
                                                 data-status="${that.BtnImportHandleStatusEnum.IMPORT.code}">${that.BtnImportHandleStatusEnum.IMPORT.tips}</button>
                                            </div>
                                        </div>
                                        <div class="yunj-import-step-content-row import-sheet-table"></div>`);
                that.sheetTableBoxEl = that.contentBoxEl.find(".import-sheet-table");
                that.dataTotalCountEl = that.contentBoxEl.find(".import-action .total .count");
                that.dataErrorCountEl = that.contentBoxEl.find(".import-action .error .count");
                that.dataSuccessCountEl = that.contentBoxEl.find(".import-action .success .count");
                that.dataFailCountEl = that.contentBoxEl.find(".import-action .fail .count");
                that.btnImportHandleEl = that.contentBoxEl.find(".btn-import-handle");
            }
            that.sheetTableBoxEl.html("");
        }

        // 设置上传数据
        _setUploadData() {
            let that = this;
            let {importItems, sheetItems, totalCount, errorCount} = that.getCurrCheckUploadData();
            if (totalCount <= 0) throw new Error("请勾选需要上传的数据行");
            that.importItems = importItems;
            that.sheetItems = sheetItems;
            that._setDataTotalCount(totalCount);
            that._setDataErrorCount(errorCount);
            that._setDataSuccessCount(0);
            that._getDataFailCount(0);
            that._setImportProgress();
            that._setBtnImportHandleStatus(that._hasCanImportData()?that.BtnImportHandleStatusEnum.IMPORT:that.BtnImportHandleStatusEnum.NO_DATA);
        }

        // 渲染工作表表格
        _renderSheetTable() {
            let that = this;
            let sheetItems = that.sheetItems;
            if (that.isSetSheet()) {
                for (let sheet in sheetItems) {
                    if (!sheetItems.hasOwnProperty(sheet)) continue;
                    that.sheetTableBoxEl.append(that._getSheetTableSingleLayout(sheet));
                    that._renderSheetLayTable(that.getCols(sheet), sheetItems[sheet], sheet);
                }
            } else {
                that.sheetTableBoxEl.append(that._getSheetTableSingleLayout());
                that._renderSheetLayTable(that.getCols(), sheetItems);
            }
        }

        // 获取单一的sheet表格结构
        _getSheetTableSingleLayout(sheet = false) {
            let id = this._getSheetTableSingleId(sheet);
            let html = "";
            if (sheet !== false) html += `<ul class="layui-tab-title">
                                <li class="layui-this">${sheet}</li>
                            </ul>`;
            html += `<div class="layui-tab-content">
                        <div class="layui-tab-item layui-show">
                            <table class="layui-table" id="${id}" lay-filter="${id}"></table>
                        </div>
                    </div>`;
            return `<div class="layui-tab">${html}</div>`;
        }

        // 渲染工作表lay表格
        _renderSheetLayTable(cols, items, sheet = false) {
            let that = this;
            let layTableCols = [{
                field: '_state',
                type: 'normal',
                title: '状态',
                fixed: 'left',
                align: 'center',
                templet: `<div><span class="layui-badge import-row-state {{ d._state.code }}" data-flag="{{ d._id }}${sheet === false ? "" : `_${sheet}`}">{{ d._state.tips }}</span></div>`
            }];
            for (let field in cols) {
                if (!cols.hasOwnProperty(field)) continue;
                layTableCols.push({field: field, type: 'normal', title: cols[field]["title"]});
            }
            let args = {
                elem: `#${that._getSheetTableSingleId(sheet)}`,
                url: '/admin/empty',
                method: 'post',
                contentType: 'application/json',
                parseData: function (res) {
                    return {
                        "code": 0,
                        "msg": 'success',
                        "count": 0,
                        "data": items
                    };
                },
                page: false,
                loading: true,
                text: {none: '暂无相关数据'},
                cols: [layTableCols],
                done: function (res) {
                    table.resize(this.id);
                }
            };
            table.render(args);
        }

        // 获取单一的sheet表格id
        _getSheetTableSingleId(sheet = false) {
            return `yunj_import_${this.importId}_step_three_table${sheet ? `_${sheet}` : ""}`;
        }

        // 获取来源表格对象
        _getRawTable() {
            let that = this;
            if (that.rawTable === false) that._setRawTable();
            return that.rawTable;
        }

        _setRawTable() {
            let that = this;
            let rawPageWin = yunj.rawPageWin();
            let rawTableId = yunj.urlParam("rawTable", "");
            that.rawTable = rawPageWin && rawTableId ? rawPageWin.yunj.table[rawTableId] : null;
        }

        // 上传
        async _import() {
            let that = this;
            that._importStart();
            while (true) {
                let isComplete = await that._importExec();
                if (isComplete === true) break;
            }
            that.importEnd();
        }

        // 上传开始
        _importStart() {
            this.importItemIdx = 0;
        }

        // 上传结束、终止
        importEnd() {
            this.importItemIdx = this.importItems.length;
        }

        /**
         * 是否正在导入
         * @return {boolean}
         */
        isImporting() {
            let itemCount = this.importItems.length;
            return this.importItemIdx > 0 && itemCount > 0 && this.importItemIdx < (itemCount - 1);
        }

        /**
         * 上传执行
         * @private
         */
        _importExec() {
            let that = this;
            return new Promise(resolve => {
                let itemIdxOptions = {};
                let items = [];
                let maxIdx = that.importItems.length - 1;
                while (items.length < that.importObj.rawArgs.limit && that.importItemIdx <= maxIdx) {
                    let idx = that.importItemIdx;
                    let item = that.importItems[idx];
                    if (item.state.code === that.importObj.DataStateEnum.WAIT.code) {
                        item.state.code = that.importObj.DataStateEnum.IMPORTING.code;
                        item.state.tips = that.importObj.DataStateEnum.IMPORTING.tips;
                        itemIdxOptions[item.id] = idx;
                        items.push(item);
                        that._setLayTableImportRowState(idx);
                    }
                    that.importItemIdx++;
                }
                if (items.length <= 0) {
                    resolve(true);
                    return;
                }

                let requestData = {builderId: that.importId, builderAsyncType: "import", items: items};
                yunj.request(yunj.url(true), requestData, "post").then(res => {
                    let dataItems = res.data.items;
                    // 更新上传数据状态
                    dataItems.forEach(item => {
                        let importItemIdx = itemIdxOptions[item.id];
                        if (yunj.isUndefined(importItemIdx)) return false;
                        that.importItems[importItemIdx] = item;
                        that._setLayTableImportRowState(importItemIdx, true);
                    });
                    resolve(that.importItemIdx >= maxIdx);
                }).catch(e => {
                    throw e;
                });
            });
        }

        /**
         * 获取可导入的数据总量
         * @param isCurr
         * @returns {number}
         * @private
         */
        _getCanImportTotalCount(isCurr = false) {
            return this._getDataTotalCount() - this._getDataErrorCount();
        }

        // 判断是否有可上传的数据
        _hasCanImportData() {
            let importCount = this._getDataSuccessCount() + this._getDataFailCount();
            let canImportTotalCount = this._getCanImportTotalCount();
            console.log(canImportTotalCount,importCount);
            return canImportTotalCount > 0 && importCount < canImportTotalCount;
        }

        // 设置上传进度
        _setImportProgress() {
            let importCount = this._getDataSuccessCount() + this._getDataFailCount();
            let canImportTotalCount = this._getCanImportTotalCount();
            let rate = importCount > 0 && canImportTotalCount > 0 ? parseInt((importCount / canImportTotalCount) * 100) : 0;
            element.progress('import_progress', `${rate < 100 ? rate : 100}%`);
        }

        /**
         * 设置表格行状态
         * @param importItemIdx 上传数据索引
         * @param incCount      是否自增数量
         * @private
         */
        _setLayTableImportRowState(importItemIdx, incCount = false) {
            let that = this;
            let item = that.importItems[importItemIdx];
            if (!item) return;
            let rowStateEl = that.contentBoxEl.find(`.import-row-state[data-flag=${item.id + (item.hasOwnProperty("sheet") ? `_${item.sheet}` : "")}]`);
            if (rowStateEl.length <= 0) return;
            let itemState = item.state;
            rowStateEl.attr("class", `layui-badge import-row-state ${itemState.code}`);
            rowStateEl.html(itemState.tips);
            if (!incCount) return;
            let codeMethodStr = itemState.code.slice(0, 1).toUpperCase() + itemState.code.slice(1);
            let setMethod = `_setData${codeMethodStr}Count`;
            let getMethod = `_getData${codeMethodStr}Count`;
            if (typeof(that[setMethod]) === "function" && typeof(that[getMethod]) === "function") that[setMethod](that[getMethod]() + 1);
            // 更新上传进度
            that._setImportProgress();
        }

        /**
         * 设置上传处理按钮状态
         * @param {object} status
         * @private
         */
        _setBtnImportHandleStatus(status = this.BtnImportHandleStatusEnum.IMPORT) {
            let that = this;
            if (!that.btnImportHandleEl) that.btnImportHandleEl = that.contentBoxEl.find(".btn-import-handle");
            let btnEl = that.btnImportHandleEl;
            btnEl.html(status.tips).data("status", status.code).attr("disabled", !status.canClick);
        }

        setEventBind() {
            let that = this;

            that.contentBoxEl.on("click", ".btn-import-handle", function (e) {
                let btnEl = $(this);
                if (btnEl.prop("disabled")) return;
                let statusCode = btnEl.data("status");
                switch (statusCode) {
                    case that.BtnImportHandleStatusEnum.IMPORT.code:
                        // 判断是否有可导入数据
                        if(!that._hasCanImportData()) {
                            that._setBtnImportHandleStatus(that.BtnImportHandleStatusEnum.NO_DATA);
                            return;
                        }
                        yunj.confirm("确认导入？", function () {
                            that._setBtnImportHandleStatus(that.BtnImportHandleStatusEnum.IMPORTING);
                            that._import().then(() => {
                                yunj.msg('数据导入完成');
                                that._setBtnImportHandleStatus(that.BtnImportHandleStatusEnum.COMPLETED);
                                if (that._getDataSuccessCount() > 0) {
                                    let rawTable = that._getRawTable();
                                    rawTable && rawTable.render();
                                }
                            }).catch(e => {
                                console.log(e);
                                yunj.error(e);
                                that._setBtnImportHandleStatus(that.BtnImportHandleStatusEnum.IMPORT);
                            });
                        });
                        break;
                    case that.BtnImportHandleStatusEnum.COMPLETED.code:
                        that.importEnd();
                        yunj.closeCurr();
                        break;
                }
                e.stopPropagation();
            })
        }

    }

    exports('ImportStepThree', ImportStepThree);
});